﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace miniGameCollection
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class MineSweeperGame : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        MouseState lastMouseState;
        KeyboardState lastKeyboardState;

        List<MinePosition> minePositions;
        List<MinePosition> flagPositions;
        string[,] displayArea;
        bool[,] visible;
        int landMineCount;
        int flagCount;
        Random random = new Random(DateTime.Now.Millisecond);

        int randomCount = 0;

        MinePosition wrongPos;

        Texture2D square;
        Texture2D flag;
        Texture2D bomb;

        int maxX;
        int maxY;

        int squareWidth = 48;
        int squareHeight = 48;

        SpriteFont gamefont;

        bool isGameOver;
        bool isWin;

        int gameLevel = 1;

        public bool DisplayMode;
        double deltaTime = 333f;
        private double lastSpentTime;

        int winCount = 0;
        int totalGameCount = 0;
        int zeroFlagCount = 0;

        public MineSweeperGame()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            this.IsMouseVisible = true;

            StartGame();

            ResizeWindows();

            base.Initialize();
        }

        private void ResizeWindows()
        {
            graphics.PreferredBackBufferWidth = squareWidth * (maxX + 1) + 150;  // set this value to the desired width of your window
            graphics.PreferredBackBufferHeight = squareHeight * (maxY + 1);   // set this value to the desired height of your window
            graphics.ApplyChanges();
        }

        private void StartGame()
        {
            minePositions = new List<MinePosition>();
            flagPositions = new List<MinePosition>();
            switch (gameLevel)
            {
                case 2:
                    displayArea = new string[16, 16];
                    visible = new bool[16, 16];
                    landMineCount = 40;
                    break;
                case 3:
                    displayArea = new string[30, 16];
                    visible = new bool[30, 16];
                    landMineCount = 99;
                    break;
                default:
                    displayArea = new string[9, 9];
                    visible = new bool[9, 9];
                    landMineCount = 10;
                    break;
            }
            InitMinePostion();
            flagCount = 0;

            isGameOver = false;
            isWin = false;

            randomCount = 0;
        }

        private void InitMinePostion()
        {
            maxX = displayArea.GetLength(0) - 1;
            maxY = displayArea.GetLength(1) - 1;
            for (int i = 0; i < landMineCount; i++)
            {
                int posX = random.Next(0, maxX + 1);
                int posY = random.Next(0, maxY + 1);
                MinePosition pos = new MinePosition(posX, posY);
                /*
                while (mineArea[posX, posY] == 1)
                {
                    posX = random.Next(0, maxX);
                    posY = random.Next(0, maxY);
                }
                mineArea[posX, posY] = 1;
                */
                while (minePositions.Contains(pos))
                {
                    posX = random.Next(0, maxX + 1);
                    posY = random.Next(0, maxY + 1);
                    pos = new MinePosition(posX, posY);
                }
                minePositions.Add(pos);
                displayArea[posX, posY] = "B";
                PutBombOnPosition(posX, posY);
            }
        }

        private void PutBombOnPosition(int posX, int posY)
        {
            for (int i = -1; i < 2; i++)
            {
                for (int j = -1; j < 2; j++)
                {
                    if (i == 0 && j == 0)
                    {
                        continue;
                    }
                    int tmpX = posX + i;
                    int tmpY = posY + j;
                    if (tmpX > -1 && tmpX <= maxX && tmpY > -1 && tmpY <= maxY)
                    {
                        ReCalNumbers(tmpX, tmpY);
                    }
                }
            }
        }

        private void ReCalNumbers(int x, int y)
        {
            if (string.IsNullOrEmpty(displayArea[x, y]))
            {
                displayArea[x, y] = "1";
            }
            else if (displayArea[x, y] == "B")
            {
                return;
            }
            else
            {
                int num = int.Parse(displayArea[x, y]);
                displayArea[x, y] = (++num).ToString();
            }
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            square = new Texture2D(GraphicsDevice, squareWidth, squareHeight);
            square.CreateBorder(1, Color.Black);

            gamefont = Content.Load<SpriteFont>("gamefont");
            flag = Content.Load<Texture2D>("flag");
            bomb = Content.Load<Texture2D>("bomb");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            // TODO: Add your update logic here
            if (flagCount >= landMineCount && !CheckIsWin())
            {
                Console.WriteLine("失败！");
                SetAllBombVisible();
                isGameOver = true;
            }
            if (!isGameOver && CheckIsWin())
            {
                Console.WriteLine("成功！");
                isGameOver = true;
                isWin = true;
            }
            else
            {
                KeyboardState keyboard = Keyboard.GetState();
                if (keyboard.IsKeyDown(Keys.Enter) || keyboard.IsKeyDown(Keys.Space))
                {
                    ReStartGame();
                }
                else if (keyboard.IsKeyDown(Keys.D1))
                {
                    gameLevel = 1;
                    RestartGameLevel();
                }
                else if (keyboard.IsKeyDown(Keys.D2))
                {
                    gameLevel = 2;
                    RestartGameLevel();
                }
                else if (keyboard.IsKeyDown(Keys.D3))
                {
                    gameLevel = 3;
                    RestartGameLevel();
                }
                else if (lastKeyboardState.IsKeyUp(Keys.A) && keyboard.IsKeyDown(Keys.A) && !isGameOver)
                {
                    AutoDigMine();
                }
                else if (lastKeyboardState.IsKeyUp(Keys.R) && keyboard.IsKeyDown(Keys.R) && !isGameOver)
                {
                    RandomDigBrickPosition();
                }
                else if (lastKeyboardState.IsKeyUp(Keys.H) && keyboard.IsKeyDown(Keys.H) && !isGameOver)
                {
                    AutoAnalysisArea();
                }
                else if (lastKeyboardState.IsKeyUp(Keys.F) && keyboard.IsKeyDown(Keys.F) && !isGameOver)
                {
                    AutoSlove();
                }
                else if (lastKeyboardState.IsKeyUp(Keys.M) && keyboard.IsKeyDown(Keys.M))
                {
                    DisplayMode = !DisplayMode;
                    if (DisplayMode)
                    {
                        isGameOver = true;
                        ClearSummary(); 
                    }
                }

                lastKeyboardState = keyboard;
            }

            MouseState mouseState = Mouse.GetState();//获取鼠标点击的状态
            MinePosition current = new MinePosition();
            current.X = mouseState.X / squareWidth;//get
            current.Y = mouseState.Y / squareHeight;
            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                if (mouseState.RightButton == ButtonState.Pressed)
                {
                    DigAllSurroundBrick(current);
                }
                else
                {
                    HandDigBrick(current);
                }
            }
            else if (lastMouseState.LeftButton == ButtonState.Pressed && mouseState.RightButton == ButtonState.Pressed)
            {
                DigAllSurroundBrick(current);
            }
            else if (lastMouseState.LeftButton != ButtonState.Pressed && lastMouseState.RightButton != ButtonState.Pressed &&
                mouseState.LeftButton != ButtonState.Pressed &&
                mouseState.RightButton == ButtonState.Pressed && CheckPosition(current) && !visible[current.X, current.Y])
            {
                FlagLandMine(current);
            }
            lastMouseState = mouseState;

            if (DisplayMode)
            {
                AutoRunGamePerSecond(gameTime);
            }

            base.Update(gameTime);
        }

        private void ClearSummary()
        {
            totalGameCount = 0;
            winCount = 0;
            zeroFlagCount = 0;
        }

        private void AutoRunGamePerSecond(GameTime gameTime)
        {
            lastSpentTime += gameTime.ElapsedGameTime.TotalMilliseconds;
            if (lastSpentTime > deltaTime)
            {
                if (isGameOver)
                {
                    ReStartGame();
                    AutoSlove();
                //if (isGameOver)
                //{
                    CheckIsWin();
                    totalGameCount++;
                    if (isWin)
                    {
                        winCount++;
                    }
                    else if(flagCount == 0)
                    {
                        zeroFlagCount++;
                    }
                //}

                    lastSpentTime = 0f; 
                }
            }
        }

        private void AutoSlove()
        {
            bool isContinue = false;
            do
            {
                isContinue = AutoAnalysisArea();
                isContinue = DoAutoDig() || isContinue;
                if (!isContinue && canRandom())
                {
                    RandomDigBrickPosition();
                    isContinue = true;
                }
            }
            while (isContinue && !isGameOver && canRandom());
        }

        private void HandDigBrick(MinePosition current)
        {
            if (flagPositions.Contains(current))
            {
                return;
            }
            if (CheckIsFailed(current))
            {
                GameFailed(current);
            }
            else
            {
                DigBrick(current);
            }
        }

        private void GameFailed(MinePosition current)
        {
            wrongPos = current;
            GameFailed();
        }

        private void RestartGameLevel()
        {
            ResizeWindows();
            StartGame();
        }

        private void GameFailed()
        {
            Console.WriteLine("失败！");
            isWin = false;
            SetAllBombVisible();
            isGameOver = true;
        }

        private void ReStartGame()
        {
            StartGame();
        }

        private void SetAllBombVisible()
        {
            foreach (MinePosition pos in minePositions)
            {
                visible[pos.X, pos.Y] = true;
            }
        }

        private void FlagLandMine(MinePosition current)
        {
            if (current.X > -1 && current.X <= maxX && current.Y > -1 && current.Y <= maxY)
            {
                if (!flagPositions.Contains(current))
                {
                    //displayArea[current.X, current.Y] = "F";
                    flagPositions.Add(current);
                    flagCount++;
                }
                else
                {
                    //失误了，还原状态比较难了
                    flagPositions.Remove(current);
                    flagCount--;
                }
            }
        }

        private void DigBrick(MinePosition current)
        {
            if (CheckPosition(current) && !visible[current.X, current.Y])
            {
                if (CheckIsFailed(current))
                {
                    return;
                }
                //displayArea[current.X, current.Y] = "O"; 
                visible[current.X, current.Y] = true;
                if (string.IsNullOrEmpty(displayArea[current.X, current.Y]))
                {
                    for (int i = -1; i < 2; i++)
                    {
                        for (int j = -1; j < 2; j++)
                        {
                            if (i == 0 && j == 0)
                            {
                                continue;
                            }
                            MinePosition newPos = new MinePosition(current.X + i, current.Y + j);
                            DigBrick(newPos);
                        }
                    }
                }
            }
            //spread others
        }

        private bool DigAllSurroundBrick(MinePosition current)
        {
            bool isDiged = false;
            if (CheckPosition(current))
            {
                if (!visible[current.X, current.Y] && string.IsNullOrEmpty(displayArea[current.X, current.Y]))
                {
                    return isDiged;
                }
                int currNum = 0;
                try
                {
                    currNum = int.Parse(displayArea[current.X, current.Y]);
                }
                catch (Exception)
                {
                    return isDiged;
                }
                if (CountNumber(current, "F") != currNum)
                {
                    return isDiged;
                }
                if (displayArea[current.X, current.Y] != "F")
                {
                    for (int i = -1; i < 2; i++)
                    {
                        for (int j = -1; j < 2; j++)
                        {
                            if (i == 0 && j == 0)
                            {
                                continue;
                            }
                            MinePosition newPos = new MinePosition(current.X + i, current.Y + j);

                            if (!flagPositions.Contains(newPos))
                            {
                                if (CheckPosition(newPos) && !visible[newPos.X, newPos.Y])
                                {
                                    isDiged = true;
                                }
                                DigBrick(newPos);
                                if (CheckIsFailed(newPos))
                                {
                                    GameFailed();
                                }
                            }

                        }
                    }
                }
            }
            return isDiged;
            //spread others
        }

        private int CountNumber(MinePosition current, string flg)
        {
            int count = 0;
            if (flg == "F")
            {
                for (int i = -1; i < 2; i++)
                {
                    for (int j = -1; j < 2; j++)
                    {
                        if (i == 0 && j == 0)
                        {
                            continue;
                        }
                        MinePosition pos = new MinePosition(current.X + i, current.Y + j);
                        if (flagPositions.Contains(pos))
                        {
                            count++;
                        }
                    }
                }
            }
            else if (flg == "unknown")
            {
                for (int i = -1; i < 2; i++)
                {
                    for (int j = -1; j < 2; j++)
                    {
                        if (i == 0 && j == 0)
                        {
                            continue;
                        }
                        MinePosition pos = new MinePosition(current.X + i, current.Y + j);
                        if (CheckPosition(pos) && !visible[pos.X, pos.Y] && !flagPositions.Contains(pos))
                        {
                            count++;
                        }
                    }
                }
            }
            return count;
        }

        private bool CheckPosition(MinePosition pos)
        {
            return pos.X >= 0 && pos.X <= maxX && pos.Y >= 0 && pos.Y <= maxY;
        }

        private bool CheckIsFailed(MinePosition position)
        {
            return minePositions.Contains(position);
        }

        private bool CheckIsWin()
        {
            if (flagCount < landMineCount)
            {
                return false;
            }
            foreach (MinePosition pos in minePositions)
            {
                if (!flagPositions.Contains(pos))
                {
                    return false;
                }
            }
            isWin = true;
            return true;
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            for (int i = 0; i < displayArea.GetLength(0); i++)
            {
                for (int j = 0; j < displayArea.GetLength(1); j++)
                {
                    Color color = Color.DarkOrange;
                    if (visible[i, j])
                    {
                        switch (displayArea[i, j])
                        {
                            case null:
                            case "":
                                color = Color.Gold;
                                break;
                            case "B":
                                color = Color.Red;
                                break;
                            case "F":
                                color = Color.Green;
                                break;
                            case "O":
                                color = Color.Blue;
                                break;
                            default:
                                color = Color.Gold;
                                break;
                        }
                        spriteBatch.Draw(square, new Vector2(i * squareWidth, j * squareHeight), color);
                        if (displayArea[i, j] == "B")
                        {
                            spriteBatch.Draw(bomb, new Vector2(i * squareWidth, j * squareHeight), Color.White);
                        }
                        else if (!string.IsNullOrEmpty(displayArea[i, j]))
                        {
                            spriteBatch.DrawString(gamefont, displayArea[i, j], new Vector2(i * squareWidth + squareWidth / 3, j * squareHeight + squareHeight / 3), Color.White);
                        }
                    }
                    else
                    {
                        spriteBatch.Draw(square, new Vector2(i * squareWidth, j * squareHeight), color);
                    }
                }
            }
            foreach (MinePosition flagPos in flagPositions)
            {
                int i = flagPos.X;
                int j = flagPos.Y;
                var color = Color.Green;
                spriteBatch.Draw(square, new Vector2(i * squareWidth, j * squareHeight), color);
                spriteBatch.Draw(flag, new Vector2(i * squareWidth + flag.Width / 4, j * squareHeight + flag.Height / 4), Color.White);
                if (isGameOver)
                {
                    if (!minePositions.Contains(flagPos))
                    {
                        spriteBatch.DrawString(gamefont, "X", new Vector2(i * squareWidth + squareWidth / 3, j * squareHeight + squareHeight / 3), Color.Red);
                    }
                    //else
                    //{
                    //    spriteBatch.DrawString(gamefont, "Y", new Vector2(i * squareWidth + squareWidth / 3, j * squareHeight + squareHeight / 3), Color.Blue);
                    //}
                }
            }
            if (isGameOver)
            {
                string result = isWin ? "Congratulations!" : "Failed!";
                string pressEnter = result + "Press Enter to restart";
                Color colorResult = isWin ? Color.Purple : Color.Red;
                Vector2 pressEnterSize = gamefont.MeasureString(pressEnter);
                spriteBatch.DrawString(gamefont, pressEnter, new Vector2(graphics.GraphicsDevice.Viewport.Width / 2 - pressEnterSize.X / 2, graphics.GraphicsDevice.Viewport.Height / 2), colorResult);
                if (!isWin && wrongPos != null)
                {
                    spriteBatch.DrawString(gamefont, "X", new Vector2(wrongPos.X * squareWidth + squareWidth / 3, wrongPos.Y * squareHeight + squareHeight / 3), Color.Red);
                }
            }
            string score = flagCount.ToString() + "/" + landMineCount;
            spriteBatch.DrawString(gamefont, score, new Vector2(squareWidth * (maxX + 1), graphics.GraphicsDevice.Viewport.Height / 2), Color.White);

            if (DisplayMode)
            {
                spriteBatch.DrawString(gamefont, "W/L(0):", new Vector2(squareWidth * (maxX + 1), graphics.GraphicsDevice.Viewport.Height / 2 + 30), Color.Yellow);
                string summary = string.Format("{0}/{1}({2})", winCount, totalGameCount - winCount, zeroFlagCount);
                spriteBatch.DrawString(gamefont, summary, new Vector2(squareWidth * (maxX + 1), graphics.GraphicsDevice.Viewport.Height / 2 + 60), Color.Yellow);
                spriteBatch.DrawString(gamefont, string.Format("{0:P2}",(float)winCount/totalGameCount), new Vector2(squareWidth * (maxX + 1), graphics.GraphicsDevice.Viewport.Height / 2 + 90), Color.Yellow);
                spriteBatch.DrawString(gamefont, string.Format("{0:P2}", (float)winCount / (totalGameCount - zeroFlagCount)), new Vector2(squareWidth * (maxX + 1), graphics.GraphicsDevice.Viewport.Height / 2 + 120), Color.Yellow);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }


        protected void AutoDigMine()
        {
            //RandomDigBrickPosition();
            bool needRepeat = false;

            do
            {
                needRepeat = DoAutoDig();
            } while (needRepeat && !isGameOver);

        }

        private bool DoAutoDig()
        {
            bool needRepeat;
            for (int i = 0; i <= maxX; i++)
            {
                for (int j = 0; j <= maxY; j++)
                {
                    if (visible[i, j] && !string.IsNullOrEmpty(displayArea[i, j]) && !isGameOver)// && displayArea[i, j] != "B"
                    {
                        int count = int.Parse(displayArea[i, j]);
                        MinePosition currentPos = new MinePosition(i, j);
                        int unKnownNum = CountNumber(currentPos, "unknown");
                        int flagNum = CountNumber(currentPos, "F");
                        if (unKnownNum == count - flagNum)
                        {
                            FlagAllSurround(currentPos);
                            //needRepeat = true;
                        }
                        //if (count > 0 && !flagPositions.Contains(currentPos))
                        //{
                        //    needRepeat = needRepeat || DigAllSurroundBrick(currentPos);
                        //    //if (DigAllSurroundBrick(currentPos))
                        //    //{
                        //    //if (i>=1)
                        //    //{
                        //    //    i = i - 1;
                        //    //}
                        //    //if (j >= 1)
                        //    //{
                        //    //    j = j - 1;
                        //    //}
                        //    //}
                        //}
                        //else
                        //{
                        //    needRepeat = false;
                        //}
                    }
                }
            }
            needRepeat = false;
            for (int i = 0; i <= maxX; i++)
            {
                for (int j = 0; j <= maxY; j++)
                {
                    if (visible[i, j] && !string.IsNullOrEmpty(displayArea[i, j]) && !isGameOver)
                    {
                        int count = int.Parse(displayArea[i, j]);
                        MinePosition currentPos = new MinePosition(i, j);
                        int unKnownNum = CountNumber(currentPos, "unknown");
                        //int flagNum = CountNumber(currentPos, "F");

                        if (count > 0 && !flagPositions.Contains(currentPos) && unKnownNum > 0)
                        {
                            needRepeat = needRepeat || DigAllSurroundBrick(currentPos);
                        }
                    }
                }
            }

            return needRepeat;
        }

        private void RandomDigBrickPosition()
        {
            //if (!canRandom())
            //{
            //    return;
            //}
            MinePosition start = GetRandomPosition();

            if (!canRandom())
            {
                List<MinePosition> leftPosList = GetAllLeftPositions();
                if (leftPosList.Count > 0)
                {
                    int index = random.Next(0, leftPosList.Count);
                    start = leftPosList[index];
                    if (leftPosList.Count == 1 && flagCount == landMineCount - 1)
                    {
                        FlagLandMine(start);
                        CheckIsWin();
                        return;
                    }
                }
            }
            HandDigBrick(start);
        }

        private MinePosition GetRandomPosition()
        {
            randomCount = 0;

            int posX = random.Next(0, maxX + 1);
            int posY = random.Next(0, maxY + 1);

            MinePosition start = new MinePosition(posX, posY);
            while ((visible[posX, posY] || flagPositions.Contains(start)) && canRandom())
            {
                posX = random.Next(0, maxX + 1);
                posY = random.Next(0, maxY + 1);
                start = new MinePosition(posX, posY);
                randomCount++;
            }

            return start;
        }

        private List<MinePosition> GetAllLeftPositions()
        {
            List<MinePosition> list = new List<MinePosition>();
            for (int i = 0; i <= maxX; i++)
            {
                for (int j = 0; j <= maxY; j++)
                {
                    if (!visible[i,j])
                    {
                        MinePosition pos = new MinePosition(i,j);
                        if (!flagPositions.Contains(pos))
                        {
                            list.Add(pos);
                        }
                    }
                }
            }
            return list;
        }

        private bool canRandom()
        {
            if (randomCount <= (maxX + 1) * (maxY + 1))
            {
                return true;
            }
            else
            {
                return GetAllLeftPositions().Count > 0;
            }
        }

        private void FlagAllSurround(MinePosition currentPos)
        {
            for (int i = -1; i < 2; i++)
            {
                for (int j = -1; j < 2; j++)
                {
                    MinePosition pos = new MinePosition(currentPos.X + i, currentPos.Y + j);
                    if (CheckPosition(pos) && !visible[pos.X, pos.Y] && !flagPositions.Contains(pos))
                    {
                        FlagLandMine(pos);
                    }
                }
            }
        }

        private bool AutoAnalysisArea()
        {
            bool isChanged = false;
            for (int i = 0; i <= maxX; i++)
            {
                for (int j = 0; j <= maxY; j++)
                {
                    if (visible[i, j] && !string.IsNullOrEmpty(displayArea[i, j]) && !isGameOver)
                    {
                        int count = int.Parse(displayArea[i, j]);
                        if (count > 0)
                        {
                            MinePosition currentPos = new MinePosition(i, j);
                            bool change = ContainsAreaAnalysis(currentPos);
                            isChanged = isChanged || change;
                        }
                    }
                }
            }
            return isChanged;
        }

        private bool ContainsAreaAnalysis(MinePosition current)
        {
            bool isChanged = false;
            int currentAllUnkown = CountNumber(current, "unknown");

            int centerBrickNum = int.Parse(displayArea[current.X, current.Y]);
            //int centerflagNum = CountLeftLineNumber(current, "F");

            int centerLeftLineUnknown = CountLeftLineNumber(current, "unknown");
            if (centerLeftLineUnknown == 0)
            {
                MinePosition rightPos = new MinePosition(current.X + 1, current.Y);
                if (CheckPosition(rightPos) && visible[rightPos.X, rightPos.Y] && !flagPositions.Contains(rightPos))
                {
                    int rightUnknown = CountRightLineNumber(rightPos, "unknown");
                    if (rightUnknown > 0)
                    {
                        int rightBrickNum = int.Parse(displayArea[rightPos.X, current.Y]);
                        int centerflagNum = CountLeftLineNumber(current, "F");
                        int rightFlagNum = CountRightLineNumber(rightPos, "F");
                        if (centerBrickNum - rightBrickNum == centerflagNum - rightFlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetRightUnknownPositions(rightPos);
                            HandDigBrick(canDigList);
                            isChanged = true;
                        }
                        else if (centerBrickNum - rightBrickNum == centerflagNum - (rightFlagNum + rightUnknown))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetRightUnknownPositions(rightPos);
                            HandFlagMine(canFlagList);
                            isChanged = true;
                        }
                    }
                }
            }
            int centerRightLineUnknown = CountRightLineNumber(current, "unknown");
            if (centerRightLineUnknown == 0)
            {
                MinePosition leftPos = new MinePosition(current.X - 1, current.Y);
                if (CheckPosition(leftPos) && visible[leftPos.X, leftPos.Y] && !flagPositions.Contains(leftPos))
                {
                    int leftUnknown = CountLeftLineNumber(leftPos, "unknown");
                    if (leftUnknown > 0)
                    {
                        //int centerBrickNum = int.Parse(displayArea[current.X, current.Y]);
                        int leftBrickNum = int.Parse(displayArea[leftPos.X, current.Y]);
                        int centerflagNum = CountRightLineNumber(current, "F");
                        int leftFlagNum = CountLeftLineNumber(leftPos, "F");
                        if (centerBrickNum - leftBrickNum == centerflagNum - leftFlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetLeftUnknownPositions(leftPos);
                            HandDigBrick(canDigList);
                            isChanged = true;
                        }
                        else if (centerBrickNum - leftBrickNum == centerflagNum - (leftFlagNum + leftUnknown))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetLeftUnknownPositions(leftPos);
                            HandFlagMine(canFlagList);
                            isChanged = true;
                        }
                    }
                }
            }
            else if (centerRightLineUnknown == 3 || centerRightLineUnknown == 2)
            {
                MinePosition right2pos = new MinePosition(current.X + 2, current.Y);
                if (CheckPosition(right2pos) && visible[right2pos.X, right2pos.Y] && !flagPositions.Contains(right2pos))
                {
                    int right2AllUnknown = CountNumber(right2pos,"unknown");
                    if (currentAllUnkown == centerRightLineUnknown && right2AllUnknown > centerRightLineUnknown)
                    {
                        int right2BrickNum = int.Parse(displayArea[right2pos.X, right2pos.Y]);
                        int right2FlagNum = CountNumber(right2pos,"F");
                        int centerflagNum = CountNumber(current,"F");
                        if (centerBrickNum - right2BrickNum == centerflagNum - right2FlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetRightUnknownPositions(right2pos);
                            AddUpDownBricks(right2pos, canDigList);
                            if (canDigList.Count > 0)
                            {
                                HandDigBrick(canDigList);
                                isChanged = true; 
                            }
                        }
                        else if (centerBrickNum - right2BrickNum == centerflagNum - (right2FlagNum + (right2AllUnknown - centerRightLineUnknown)))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetRightUnknownPositions(right2pos);
                            AddUpDownBricks(right2pos,canFlagList);
                            if (canFlagList.Count > 0)
                            {
                                HandFlagMine(canFlagList);
                                isChanged = true; 
                            }
                        }
                    }
                    else if (currentAllUnkown > centerRightLineUnknown && right2AllUnknown == centerRightLineUnknown)
                    {
                        int right2BrickNum = int.Parse(displayArea[right2pos.X, right2pos.Y]);
                        int right2FlagNum = CountNumber(right2pos, "F");
                        int centerflagNum = CountNumber(current, "F");
                        if (centerBrickNum - right2BrickNum == centerflagNum - right2FlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetLeftUnknownPositions(current);
                            AddUpDownBricks(current, canDigList);
                            if (canDigList.Count > 0)
                            {
                                HandDigBrick(canDigList);
                                isChanged = true;
                            }
                        }
                        else if (right2BrickNum - centerBrickNum == right2FlagNum  - (centerflagNum + (currentAllUnkown - centerRightLineUnknown)))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetLeftUnknownPositions(current);
                            AddUpDownBricks(current, canFlagList);
                            if (canFlagList.Count > 0)
                            {
                                HandFlagMine(canFlagList);
                                isChanged = true;
                            }
                        }
                    }
                }
            }

            int centerUpRowUnknown = CountUpRowNumber(current, "unknown");
            if (centerUpRowUnknown == 0)
            {
                MinePosition downPos = new MinePosition(current.X, current.Y + 1);
                if (CheckPosition(downPos) && visible[downPos.X, downPos.Y] && !flagPositions.Contains(downPos))
                {
                    int downUnknown = CountDownRowNumber(downPos, "unknown");
                    if (downUnknown > 0)
                    {
                        //int centerBrickNum = int.Parse(displayArea[current.X, current.Y]);
                        int downBrickNum = int.Parse(displayArea[downPos.X, downPos.Y]);
                        int centerflagNum = CountUpRowNumber(current, "F");
                        int downFlagNum = CountDownRowNumber(downPos, "F");
                        if (centerBrickNum - downBrickNum == centerflagNum - downFlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetDownUnknownPositions(downPos);
                            HandDigBrick(canDigList);
                            isChanged = true;
                        }
                        else if (centerBrickNum - downBrickNum == centerflagNum - (downFlagNum + downUnknown))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetDownUnknownPositions(downPos);
                            HandFlagMine(canFlagList);
                            isChanged = true;
                        }
                    }
                }
            }

            int centerDownRowUnknown = CountDownRowNumber(current, "unknown");
            if (centerDownRowUnknown == 0)
            {
                MinePosition upPos = new MinePosition(current.X, current.Y - 1);
                if (CheckPosition(upPos) && visible[upPos.X, upPos.Y] && !flagPositions.Contains(upPos))
                {
                    int upUnknown = CountUpRowNumber(upPos, "unknown");
                    if (upUnknown > 0)
                    {
                        //int centerBrickNum = int.Parse(displayArea[current.X, current.Y]);
                        int upBrickNum = int.Parse(displayArea[upPos.X, upPos.Y]);
                        int centerflagNum = CountDownRowNumber(current, "F");
                        int upFlagNum = CountUpRowNumber(upPos, "F");
                        if (centerBrickNum - upBrickNum == centerflagNum - upFlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetUpUnknownPositions(upPos);
                            HandDigBrick(canDigList);
                            isChanged = true;
                        }
                        else if (centerBrickNum - upBrickNum == centerflagNum - (upFlagNum + upUnknown))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetUpUnknownPositions(upPos);
                            HandFlagMine(canFlagList);
                            isChanged = true;
                        }
                    }
                }
            }
            else if (centerDownRowUnknown == 3 || centerDownRowUnknown == 2)
            {
                MinePosition down2pos = new MinePosition(current.X,current.Y + 2);
                if (CheckPosition(down2pos) && visible[down2pos.X, down2pos.Y] && !flagPositions.Contains(down2pos))
                {
                    int down2AllUnknown = CountNumber(down2pos,"unknown");
                    if (currentAllUnkown == centerDownRowUnknown && down2AllUnknown > centerDownRowUnknown)
                    {
                        int centerflagNum = CountNumber(current, "F");

                        int down2BrickNum = int.Parse(displayArea[down2pos.X, down2pos.Y]);
                        int down2FlagNum = CountNumber(down2pos, "F");

                        if (centerBrickNum - down2BrickNum == centerflagNum - down2FlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetDownUnknownPositions(down2pos);
                            AddLeftRightBricks(down2pos, canDigList);
                            if (canDigList.Count > 0)
                            {
                                HandDigBrick(canDigList);
                                isChanged = true;
                            }
                        }
                        else if (centerBrickNum - down2BrickNum == centerflagNum - (down2FlagNum + (down2AllUnknown - centerDownRowUnknown)))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetDownUnknownPositions(down2pos);
                            AddLeftRightBricks(down2pos, canFlagList);
                            if (canFlagList.Count > 0)
                            {
                                HandFlagMine(canFlagList);
                                isChanged = true;
                            }
                        }
                    }
                    else if (currentAllUnkown > centerDownRowUnknown && down2AllUnknown == centerDownRowUnknown)
                    {
                        int centerflagNum = CountNumber(current, "F");

                        int down2BrickNum = int.Parse(displayArea[down2pos.X, down2pos.Y]);
                        int down2FlagNum = CountNumber(down2pos, "F");
                        
                        if (centerBrickNum - down2BrickNum == centerflagNum - down2FlagNum)
                        {
                            //没有雷了
                            List<MinePosition> canDigList = GetUpUnknownPositions(current);
                            AddLeftRightBricks(current, canDigList);
                            if (canDigList.Count > 0)
                            {
                                HandDigBrick(canDigList);
                                isChanged = true;
                            }
                        }
                        else if (down2BrickNum - centerBrickNum == down2FlagNum - (centerflagNum + (currentAllUnkown - centerDownRowUnknown)))
                        {
                            //剩下的都是雷
                            List<MinePosition> canFlagList = GetUpUnknownPositions(current);
                            AddLeftRightBricks(current, canFlagList);
                            if (canFlagList.Count > 0)
                            {
                                HandFlagMine(canFlagList);
                                isChanged = true;
                            }
                        }
                    }
                }
            }

            return isChanged;
        }

        private void AddLeftRightBricks(MinePosition pos, List<MinePosition> canFlagList)
        {
            MinePosition tmp1 = new MinePosition(pos.X - 1, pos.Y);
            if (CheckPosition(tmp1) && !visible[tmp1.X, tmp1.Y] && !flagPositions.Contains(tmp1))
            {
                canFlagList.Add(tmp1);
            }
            MinePosition tmp2 = new MinePosition(pos.X + 1, pos.Y);
            if (CheckPosition(tmp2) && !visible[tmp2.X, tmp2.Y] && !flagPositions.Contains(tmp2))
            {
                canFlagList.Add(tmp2);
            }
        }

        private void AddUpDownBricks(MinePosition right2pos, List<MinePosition> canDigList)
        {
            MinePosition tmp1 = new MinePosition(right2pos.X, right2pos.Y - 1);
            if (CheckPosition(tmp1) && !visible[tmp1.X, tmp1.Y] && !flagPositions.Contains(tmp1))
            {
                canDigList.Add(tmp1);
            }
            MinePosition tmp2 = new MinePosition(right2pos.X, right2pos.Y + 1);
            if (CheckPosition(tmp2) && !visible[tmp2.X, tmp2.Y] && !flagPositions.Contains(tmp2))
            {
                canDigList.Add(tmp2);
            }
        }

        private List<MinePosition> GetUpUnknownPositions(MinePosition upPos)
        {
            List<int> x = new List<int>() { -1, 0, 1 };
            List<int> y = new List<int>() { -1 };

            return GetPositionListOfRange(upPos, "unknown", x, y);
        }

        private List<MinePosition> GetDownUnknownPositions(MinePosition downPos)
        {
            List<int> x = new List<int>() { -1, 0, 1 };
            List<int> y = new List<int>() { 1 };

            return GetPositionListOfRange(downPos, "unknown", x, y);
        }

        private int CountDownRowNumber(MinePosition current, string flg)
        {
            List<int> y = new List<int>() { 1 };
            List<int> x = new List<int>() { -1, 0, 1 };

            return CountNumOfRange(current, flg, x, y);
        }

        private int CountUpRowNumber(MinePosition current, string flg)
        {
            List<int> y = new List<int>() { -1 };
            List<int> x = new List<int>() { -1, 0, 1 };

            return CountNumOfRange(current, flg, x, y);
        }

        private void HandFlagMine(List<MinePosition> canFlagList)
        {
            foreach (MinePosition pos in canFlagList)
            {
                FlagLandMine(pos);
            }
        }

        private void HandDigBrick(List<MinePosition> canDigList)
        {
            foreach (MinePosition pos in canDigList)
            {
                HandDigBrick(pos);
            }
        }

        private List<MinePosition> GetRightUnknownPositions(MinePosition current)
        {
            List<int> x = new List<int>() { 1 };
            List<int> y = new List<int>() { -1, 0, 1 };

            return GetPositionListOfRange(current, "unknown", x, y);
        }

        private List<MinePosition> GetLeftUnknownPositions(MinePosition current)
        {
            List<int> x = new List<int>() { -1 };
            List<int> y = new List<int>() { -1, 0, 1 };

            return GetPositionListOfRange(current, "unknown", x, y);
        }

        private int CountLeftLineNumber(MinePosition current, string flg)
        {
            List<int> x = new List<int>() { -1 };
            List<int> y = new List<int>() { -1, 0, 1 };

            return CountNumOfRange(current, flg, x, y);
        }

        private int CountNumOfRange(MinePosition current, string flg, List<int> x, List<int> y)
        {
            int count = 0;
            foreach (int i in x)
            {
                foreach (int j in y)
                {
                    if (i == 0 && j == 0)
                    {
                        continue;
                    }
                    if (flg == "F")
                    {
                        MinePosition pos = new MinePosition(current.X + i, current.Y + j);
                        if (flagPositions.Contains(pos))
                        {
                            count++;
                        }
                    }
                    else if (flg == "unknown")
                    {

                        MinePosition pos = new MinePosition(current.X + i, current.Y + j);
                        if (CheckPosition(pos) && !visible[pos.X, pos.Y] && !flagPositions.Contains(pos))
                        {
                            count++;
                        }
                    }
                }
            }

            return count;
        }

        private List<MinePosition> GetPositionListOfRange(MinePosition current, string flg, List<int> x, List<int> y)
        {
            List<MinePosition> count = new List<MinePosition>();
            foreach (int i in x)
            {
                foreach (int j in y)
                {
                    if (i == 0 && j == 0)
                    {
                        continue;
                    }
                    if (flg == "F")
                    {
                        MinePosition pos = new MinePosition(current.X + i, current.Y + j);
                        if (flagPositions.Contains(pos))
                        {
                            count.Add(pos);
                        }
                    }
                    else if (flg == "unknown")
                    {

                        MinePosition pos = new MinePosition(current.X + i, current.Y + j);
                        if (CheckPosition(pos) && !visible[pos.X, pos.Y] && !flagPositions.Contains(pos))
                        {
                            count.Add(pos);
                        }
                    }
                }
            }

            return count;
        }

        private int CountRightLineNumber(MinePosition current, string flg)
        {
            List<int> x = new List<int>() { 1 };
            List<int> y = new List<int>() { -1, 0, 1 };
            return CountNumOfRange(current, flg, x, y);
        }
    }
}
